跳到主要内容

日志工具--LOG4J

概述

参考资料 最详细的 Log4j 使用教程 参考资料 2020年Java进阶教程,全面学习多种 java 日志框架

1、日志系统可以控制日志信息传输的目的地:控制台、文件、GUI组件

2、通过定义每一条日志信息的级别,可以更加细致的控制日志的生成过程

3、通过一个 配置文件 来灵活配置,而不需要修改应用代码

日志级别

每个Logger都被了一个日志级别(log level),用来控制日志信息的输出。日志级别从高到低分为:

  • OFF 最高等级,用于关闭所有日志记录。
  • FATAL 严重错误,不会影响系统运行
  • ERROR 错误信息,指出虽然发生错误事件,但仍然不影响系统的继续运行。
  • WARN 警告信息,表明会出现潜在的错误情形。
  • INFO 运行信息,记录数据连接、网络连接、IO操作等等
  • DEBUG 调试信息,一般用在开发中使用,记录程序变量参数传递信息等等
  • trace 追踪信息,记录程序所有的流程信息
  • ALL 最低等级,用于打开所有日志记录。

设置了高级别的日志级别,低级别的日志就不会给打印出来

例如:下面设置的级别是 INFO 那么 DEBUG、trace 级别的消息就不会给打印出来

log4j.rootLogger=INFO,stdout,logs

主要构成

日志的三个主要配置项:

日志信息的优先级:日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,分别用来指定这条日志信息的重要程度

日志信息的输出目的地:日志信息的输出目的地指定了日志将打印到控制台还是文件中

日志信息的输出格式:而输出格式则控制了日志信息的显 示内容。

Log4j 的主要组件:

Loggers:日志记录器 控制日志的输出级别与日志是否输出

Appenders:输出端 指定日志的输出方式(输出到控制台、文件等)

Layout:日志格式化器 控制日志信息的输出格式

导入依赖

<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>

导入的各种包的区别

log4j:包含.class (过时,现在已经迁移到 core 里了) log4j-api:包含 .class 但是只是一堆接口而已,但是并不包含日志功能 log4j-core:包含 .class 与 .java 也就是源码

配置文件

如果单独使用这个日志框架(不使用 spring boot 这类框架),需要手动编写配置文件,配置文件名称叫做 log4j.properties 且要丢到 resources 根目录里面去

配置 Logger

分为根 Logger 和 子 Logger

子级的 level 继承自父级,低于父级的信息会被过滤掉

配置根 Logger 其语法为:

log4j.rootLogger = [ level ] , appendedName, appendedName, …

配置子 Logger 的语法

就是用来控制某个包下的 Logger

如下,设置 com.alsritter.test 包下的 level 为 error,标识符为 E

log4j.logger.com.alsritter.test=error,E
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =../logs/error.log

level 设置

level 可以填写: OFFFATALERRORWARNINFODEBUGALL 或者自定义的级别。

Log4j 建议只使用四个级别,优先级从高到低分别是 ERRORWARNINFODEBUG

在这里定义的级别 就是应用程序中 相应级别的日志信息的开关。

比如在这里只定义了 INFO 级别,则应用程序中所有 DEBUG 级别的日志信息将不被打印出来。

设置标识符

log4j.rootLogger=INFO,stdout,logs

这个 appenderName 就是一个标识符(appenderName 可以随便写自定义的名字)

作用就是添加不同的配置,每个标识符都是一个单独的配置,例如可以设置不同的输出目的地

# 例如自定义一个叫做 stdout 的标识符
log4j.rootLogger=INFO,stdout

### 输出信息到控制台 ###
# 指定控制台日志输出的 appender
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out

设置输出端

其中,Log4j提供的appender有以下几种:

Appender类型目的地
org.apache.log4j.ConsoleAppender控制台
org.apache.log4j.FileAppender文件
org.apache.log4j.DailyRollingFileAppender每天的日志文件建一个新的来存储
org.apache.log4j.RollingFileAppender文件大小到达指定尺寸的时候产生一个新的文件
org.apache.log4j.WriterAppender将日志信息以流格式发送到任意指定的地方

使用例:

log4j.rootLogger=INFO,D
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender

设置输出格式

布局器 Layouts 用于指定输出日志的格式

Log4J 常用的 Layouts:

格式化器类型作用
HTMLLayout格式化日志输出为HTML表格形式
SimpleLayout简单的日志输出格式化,打印的日志格式为(info-message)
PatternLayout最强大的格式化期,可以根据自定义格式输出日志,如果没有指定转换格式,就是用默认的转换格式

SimpleLayout 就是使用默认的输出样式

使用例:

log4j.rootLogger=INFO,D
log4j.appender.D.layout = org.apache.log4j.PatternLayout

日志输出样式

参考资料 Log4j详细介绍(七)----日志格式化器Layout

参数描述实例
%m输出代码中指定的消息输出日志,即log.info(“”),log.debug(“”)参数
%p输出优先级,即DEBUG,INFO,WARN,ERROR,FATALDEBUG,INFO,ERROR,FITAL等
%r输出自应用启动到输出该log信息耗费的毫秒数%r将输出300
%c输出所属的类目,通常就是所在类的全名,允许使用%c{数字}输出部分的名字(从右边往左边数)。%C将输出com.log4j.Log4jTest
%C{1}将输出Log4jTest
%C{2}将输出log4j.Log4jTest
%C{3}将输出com.log4j.Log4jTest
%t输出产生该日志事件的线程名%t将输出main,Thread-0,Thread-1等
%n输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”换行
%d输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921%d将输出2013-06-06 22:24:25,353
%d{yyyy-MM-dd}将输出2013-06-06
%d{ABSOLUTE}将输出22:24:25,353
%d{DATE}将输出06六月2013 22:24:25,253
%l输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)%l将输出com.log4j.test.Log4jTest.main(Log4jTest.java:50)
%F输出日志消息时所在的文件名称
%L输出代码的行号,不过一般不用加这个,因为%l里就带了
%%输出一个%
格式对齐方式最小宽度最大宽度描述实例
[%10p]右对齐10正数右对齐,最小宽度   ERROR]
[%-10p]左对齐10负数左对齐,最小宽度[ERROR    ]
[%.4p]4最大宽度[ERROR]
[%10.20p]右对齐1020正数右对齐,最大最小宽度   ERROR]
[%-10.20p]左对齐1020负数左对齐,最大最小宽度[ERROR    ]

使用例:

log4j.appender.logs.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} from:%F%nMethod:%l%n%m%n

输出的消息为:

[INFO ] 2020-06-14 17:18:04,947 from:UserTest.java
Method:com.alsritter.test.UserTest.testLog4j(UserTest.java:36)
普通信息
logger.info("普通信息");

上面这些级别是定义在org.apache.log4j.Level类中。Log4j只建议使用4个级别,优先级从高到低分别是error,warn,info和debug。

模板

### 指定RootLogger顶级父元素默认配置信息
# 指定日志级别=INFO,使用的appender= stdout、logs 这两个标识符
log4j.rootLogger=INFO,stdout,logs
log4j.addivity.org.apache=true

### 输出信息到控制台 ###
# 指定控制台日志输出的appender
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
# 指定消息格式layout
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n


### 打印到log文件 ###
log4j.appender.logs = org.apache.log4j.FileAppender
log4j.appender.logs.layout = org.apache.log4j.PatternLayout
log4j.appender.logs.File =../logs/logs.log
log4j.appender.logs.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

使用例步骤

得到记录器

参考资料 Logger之Logger.getLogger(CLass)

使用 Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。

// 使用的是 Log4j 工具类下的静态方法
public static Logger getLogger( String name)

注意,这个全类名应该用当前类的全类名,因为 Logger 是用来追踪当前类的信息

static Logger logger = Logger.getLogger(MyTest.getClass());

读取配置文件

当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:

// 自动快速地使用默认的Log4j环境。  
BasicConfigurator.configure ();

// 读取 Properties 形式的配置文件
PropertyConfigurator.configure ( String configFilename)

// 读取 XML 形式的配置文件
DOMConfigurator.configure ( String filename )

输出日志

当上两个必要步骤执行完毕,就可以轻松地使用不同优先级别的日志记录语句插入到想记录日志的任何地方,其语法如下:

Logger.debug ( Object message ) ;  
Logger.info ( Object message ) ;
Logger.warn ( Object message ) ;
Logger.error ( Object message ) ;

具体的使用例


// 如果使用了BasicConfigurator则是采用默认配置信息
static {
BasicConfigurator.configure();
}


@Test
public void testLog4j(){
// 初始化
Logger logger = Logger.getLogger(this.getClass());
// 读取配置文件的信息,其实不加这条语句也行,
// 不加上BasicConfigurator.configure()默认值就是使用log4j.properties里面的配置信息,
// 只是在这里显示指定了配置文件,优先使用用户显示指定的配置文件
PropertyConfigurator.configure(this.getClass().getResourceAsStream("/log4j.properties");
logger.fatal("致命错误");
logger.error("普通错误");
logger.trace("警告信息");
logger.info("普通信息");
logger.debug("调试信息");
logger.trace("堆栈信息");
}

注:一般不使用上面那样在方法里实例化 直接使用静态字段比较好,防止每次实例化都创建一个新的Logger 如下

private static final Logger logger = Logger.getLogger(MyTest.class);

在 MyBatis 使用

先导入包

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

然后修改配置文件的日志为LOG4J

<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>

配置文件

# 将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

# 控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

# 文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=../logs/sqlLog.log
log4j.appender.file.Encoding=utf-8
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} from:%F%nMethod:%l%n%m%n

# 日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

乱码问题: Reader entry: 会出现乱码 解决办法:把别名去掉,使用全类名就没有问题了,至于全类名就是使用不了了...

整合到 slf4j

如果使用 Maven,则只需添加适配器 jar 包依赖即可:

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
<scope>test</scope>
</dependency>

在类路径下创建 log4j.properties 配置文件,这样 log4j 会自动加载配置文件。

# rootLogger参数分别为:根Logger级别,输出器stdout,输出器log
log4j.rootLogger = info,stdout,log

# 输出信息到控制台
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d [%-5p] %l %rms: %m%n

# 输出DEBUG级别以上的日志到 ./logs/debug.log
log4j.appender.log = org.apache.log4j.DailyRollingFileAppender
log4j.appender.log.DatePattern = '.'yyyy-MM-dd
log4j.appender.log.File = ./log/debug.log
log4j.appender.log.Encoding = UTF-8

#log4j.appender.log.Threshold = INFO
log4j.appender.log.layout = org.apache.log4j.PatternLayout
log4j.appender.log.layout.ConversionPattern = %d [%-5p] (%c.%t): %m%n